﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using pwestcott.Util;
using NUnit.Framework;

namespace pwestcott.Util.Tests.Essence.Comparer
{
    [TestFixture]
    public class ComparerTests
    {
        class MyClass
        {
            public MyClass(int i, string s, DateTime d)
            {
                MyInt = i;
                MyString = s;
                MyDateTime = d;
            }

            public int MyInt { get; private set; }
            public string MyString { get; private set; }
            public DateTime MyDateTime { get; private set; }
        }

        class ManualComparer : IComparer<MyClass>
        {
            public int Compare(MyClass lhs, MyClass rhs)
            {
                if (rhs == null)
                    return -1;
                if (ReferenceEquals(lhs, rhs))
                    return 0;

                int result;
                result = lhs.MyInt.CompareTo(rhs.MyInt);
                if (result != 0)
                    return result;
                if (lhs.MyString == null)
                {
                    if (rhs.MyString != null)
                        return 1;
                }
                else
                {
                    result = lhs.MyString.CompareTo(rhs.MyString);
                    if (result != 0)
                        return result;
                }
                result = lhs.MyDateTime.CompareTo(rhs.MyDateTime);
                if (result != 0)
                    return result;

                return 0;
            }
        }

        static readonly int[] ints = { 42, int.MinValue, -1, 93, int.MaxValue };
        static readonly string[] strings = { "Mary", "Mark", "Paul", null, "James" };
        static readonly DateTime[] dates = { new DateTime(1976, 11, 23), DateTime.MaxValue, new DateTime(1973, 11, 13), new DateTime(1999, 4, 18), DateTime.MinValue };

        private void Loop(Action<MyClass> getData)
        {
            for (int i = 0; i < ints.Length; ++i)
            {
                var theInt = ints[i];
                for (int j = 0; j < strings.Length; ++j)
                {
                    var theString = strings[j];
                    for (int k = 0; k < dates.Length; ++k)
                    {
                        var theDate = dates[k];

                        getData(new MyClass(theInt, theString, theDate));
                    }
                }
            }
        }

        [Test]
        public void TestComparer()
        {
            var manualComparer = new ManualComparer();
            var essenceComparer = Essence<MyClass>.CreateComparer(new [] {"MyInt", "MyString", "MyDateTime"});

            var myClass = new MyClass(ints[0], strings[0], dates[0]);

            Loop(next =>
            {
                Assert.AreEqual(manualComparer.Compare(myClass, next), essenceComparer.Compare(myClass, next));
            });
        }
    }
}
